#!/bin/bash

# 数据库备份脚本
# 功能：备份MySQL 8.x 和MongoDB 3.8数据库
# 使用方法：根据需要修改配置部分，然后直接运行
# 说明：
#   1、mysql存字段（表结构）
#   2、mongodb存储表的具体行数据（动态字段灵活）

# 配置部分 ==============================================

# 通用配置
BACKUP_DIR="/home/lihao/data/backups/db"         # 备份文件存储目录
DAYS_TO_KEEP=7                        # 保留最近多少天的备份
DATE=$(date +%Y-%m-%d_%H:%M:%S)       # 当前日期时间格式
LOG_FILE_DIR="/home/lihao/log"
LOG_FILE_NAME="db_backup.log"
LOG_FILE="${LOG_FILE_DIR}/${LOG_FILE_NAME}"  # 日志文件路径

# MySQL配置
MYSQL_HOST="lyw.cdbytech.top"                # MySQL主机地址
MYSQL_PORT="3306"                     # MySQL端口
MYSQL_USER="lihao"              # MySQL备份用户
MYSQL_PASSWORD="p081742lh^mysql"  # MySQL备份用户密码
MYSQL_DATABASES=("byjs")         # 要备份的数据库列表，用空格分隔

# MongoDB配置
MONGO_HOST="lyw.cdbytech.top"                # MongoDB主机地址
MONGO_PORT="27017"                    # MongoDB端口
MONGO_USER="lihao"              # MongoDB备份用户(如果没有设置认证可留空)
MONGO_PASSWORD="p081742lh"  # MongoDB备份用户密码(如果没有设置认证可留空)
MONGO_DATABASES=("bytech")         # 要备份的MongoDB数据库列表，多个用空格分开

# 函数定义 ==============================================

# 记录日志函数
log() {
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}

# 检查并创建备份目录
init_backup_dir() {
    if [ ! -d "$BACKUP_DIR" ]; then
        mkdir -p "$BACKUP_DIR"
        log "创建备份目录: $BACKUP_DIR"
    fi
    if [ ! -d "$LOG_FILE_DIR" ]; then
        mkdir -p "$LOG_FILE_DIR"
        log "创建备份目录: $LOG_FILE_DIR"
    fi
    echo "Creating file with content" > $LOG_FILE
}

# 备份MySQL数据库
backup_mysql() {

    # 检查mysqldump是否存在
    if ! which mysqldump >/dev/null 2>&1; then
        echo "错误: mysqldump命令不存在, 请检查MySQL客户端是否安装( sudo apt install mysql-server )" >&2
        exit 1
    fi

    log "开始备份【 MySQL 】数据库..."

    for DB_NAME in "${MYSQL_DATABASES[@]}"; do
        BACKUP_FILE="$BACKUP_DIR/mysql_${DB_NAME}_$DATE.sql.gz"

        log "正在备份MySQL数据库: $DB_NAME"

        # 使用mysqldump备份并压缩
        #  -u 或 --user: 指定 MySQL 用户名
        #  -p 或 --password: 提示输入密码(建议使用这种而不是直接在命令中写密码)
        #  -h 或 --host: 指定 MySQL 服务器地址
        #  -P 或 --port: 指定 MySQL 服务器端口
        #  --databases: 备份一个或多个数据库
        #  --all-databases: 备份所有数据库
        #  --no-data 或 -d: 只备份表结构，不备份数据
        #  --no-create-info 或 -t: 只备份数据，不备份表结构
        #  --add-drop-table: 在创建表前添加 DROP TABLE 语句
        #  --skip-lock-tables: 不锁定表(适用于 MyISAM)
        #  --single-transaction: 对 InnoDB 使用事务保证一致性
        #  --routines: 备份存储过程和函数
        #  --triggers: 备份触发器
        #  --events: 备份事件
        #  --hex-blob: 以十六进制格式导出二进制数据

        mysqldump -h$MYSQL_HOST -P$MYSQL_PORT -u$MYSQL_USER -p$MYSQL_PASSWORD \
            --single-transaction --routines --triggers --databases $DB_NAME | gzip > $BACKUP_FILE

        if [ $? -eq 0 ]; then
            log "MySQL数据库 $DB_NAME 备份成功: $BACKUP_FILE"
        else
            log "MySQL数据库 $DB_NAME 备份失败!"
        fi
    done

    log "--- MySQL数据库备份完成 ----"
    log "--------------- 分割线 -------------------"
}

# 备份MongoDB数据库
backup_mongodb() {

    # 检查mongodump是否存在
    if ! command -v mongodump >/dev/null 2>&1; then
        echo "错误: mongodump命令不存在, 请检查mongodb客户端是否安装( sudo apt install mongodb )" >&2
        exit 1
    fi

    log "开始备份【 MongoDB 】数据库..."

    for DB_NAME in "${MONGO_DATABASES[@]}"; do
        BACKUP_FILE="$BACKUP_DIR/mongodb_${DB_NAME}_$DATE.archive"

        log "正在备份MongoDB数据库: $DB_NAME"

        # 构建认证参数
        AUTH_PARAMS=""
        if [ -n "$MONGO_USER" ]; then
            AUTH_PARAMS="--username $MONGO_USER --password $MONGO_PASSWORD \
            --authenticationDatabase bytech --authenticationMechanism SCRAM-SHA-1"
        fi

        # 使用mongodump备份
        mongodump --host $MONGO_HOST --port $MONGO_PORT $AUTH_PARAMS \
            --db $DB_NAME --archive=$BACKUP_FILE --gzip

        if [ $? -eq 0 ]; then
            log "MongoDB数据库 $DB_NAME 备份成功: $BACKUP_FILE"
        else
            log "MongoDB数据库 $DB_NAME 备份失败!"
        fi
    done

    log "--- MongoDB数据库备份完成 ---"
}

# 清理旧备份文件
clean_old_backups() {
    log "开始清理超过 $DAYS_TO_KEEP 天的旧备份文件..."

    find $BACKUP_DIR -name 'mysql_*.sql.gz' -mtime +$DAYS_TO_KEEP -exec rm {} \;
    find $BACKUP_DIR -name 'mongodb_*.archive' -mtime +$DAYS_TO_KEEP -exec rm {} \;

    log "旧备份文件清理完成"
}

# 主程序 ==============================================

# 初始化日志
echo "=== 数据库备份开始 [$(date +'%Y-%m-%d %H:%M:%S')] ===" > $LOG_FILE
echo "=== 开始备份【 MySQL 】和【 MongoDB 】数据库 ==="

# 检查并创建备份目录
init_backup_dir

# 备份MySQL
backup_mysql

# 备份MongoDB
backup_mongodb

# 清理旧备份
clean_old_backups

# 完成
log "=== 数据库备份完成 ==="
echo "备份完成，详情请查看日志: $LOG_FILE"
